package hichecker.university;

import java.util.UUID;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;

/**
 * Class representing a student at the university.
 */
@XmlType(propOrder = {"id", "firstName", "lastName", "matrikel", "studyCourse"})
public class Student {

	private @XmlElement UUID id;
	private @XmlElement String firstName;
	private @XmlElement String lastName;
	private @XmlElement String matrikel;
	private @XmlElement String studyCourse;

	/**
	 * Constructs a student and a creates a unique id
	 */
	public Student() {
		id = UUID.randomUUID();
	}

	/**
	 * Constructs a student with the unique id
	 *
	 * @param uuid
	 */
	public Student(UUID uuID) {
		this.id = uuID;
	}

	/**
	 * Constructor that copies the object
	 *
	 * @param student
	 */
	public Student(Student student) {
		id = student.getID();
		firstName = student.getFirstName();
		lastName = student.getLastName();
		matrikel = student.getMatrikel();
		studyCourse = student.getStudyCourse();
	}

	@XmlTransient
	public UUID getID() {
		return id;
	}

	/**
	 * Sets the unique id for this student
	 *
	 * @param id
	 */
	public void setID(UUID id) {
		this.id = id;
	}


	/**
	 * Returns the first name of this student
	 *
	 * @return
	 */
	@XmlTransient
	public String getFirstName() {
		return firstName;
	}

	/**
	 * Sets the first name for this student
	 *
	 * @param firstName
	 */
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	/**
	 * Returns the last name of this student
	 *
	 * @return
	 */
	@XmlTransient
	public String getLastName() {
		return lastName;
	}

	/**
	 * Sets the last name for this student
	 *
	 * @param lastName
	 */
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	/**
	 * Returns the matrikel number of this student
	 *
	 * @return
	 */
	@XmlTransient
	public String getMatrikel() {
		return matrikel;
	}

	/**
	 * Sets the matrikel number for this student
	 *
	 * @param matrikel
	 */
	public void setMatrikel(String matrikel) {
		this.matrikel = matrikel;
	}

	/**
	 * Returns the course of study of this student
	 *
	 * @return
	 */
	@XmlTransient
	public String getStudyCourse() {
		return studyCourse;
	}

	/**
	 * Sets the course of study for this student
	 *
	 * @param studyCourse
	 */
	public void setStudyCourse(String studyCourse) {
		this.studyCourse = studyCourse;
	}

	/**
	 * Copies all values (expect of the id) from the new student to the old one
	 *
	 * @param oldStudent
	 * @param newStudent
	 */
	public void takeOverValues(Student newStudent) {
		lastName  = newStudent.getLastName();
		firstName = newStudent.getFirstName();
		matrikel = newStudent.getMatrikel();
		studyCourse = newStudent.getStudyCourse();
	}

	/**
	 * Indicates whether some other object is equal to this one.
	 *
	 * @return true if both objects have the same id, or the same first- and lastname or the same
	 *         matrikel number. false otherwise
	 */
	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof Student))
			return false;

		Student student = (Student) obj;
		UUID id = student.getID();
		String thatFName = student.getFirstName() == null ? "" : student.getFirstName().toLowerCase();
		String thatLName = student.getLastName() == null ? "" : student.getLastName().toLowerCase();
		String thatMat = student.getMatrikel() == null ? "" : student.getMatrikel().toLowerCase();

		String thisFName = getFirstName() == null ? "" : getFirstName().toLowerCase();
		String thisLName = getLastName() == null ? "" : getLastName().toLowerCase();
		String thisMat = getMatrikel() == null ? "" : getMatrikel().toLowerCase();

		return (id.equals(getID())
				|| (thatFName.equals(thisFName) && thatLName.equals(thisLName))
				|| (thatMat.equals(thisMat) && thatMat.length() > 0));
	}

	@Override
	public int hashCode() {
		return (id).hashCode();
	}

	@Override
	public String toString() {
		return firstName + " " + lastName + " " + matrikel + " " + studyCourse;
	}

}
